using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Reflection;
using System.Windows.Forms;
using Sixeyed.CacheAdapter.Interfaces;

namespace Sixeyed.CacheAdapter.Management.Dialogs
{
	/// <summary>
	/// Dialog for selecting a .NET type that implements <see cref="ICacheProvider"/>
	/// </summary>
    public class CacheProviderTypeName : System.Windows.Forms.Form
	{
		private string typeName = string.Empty;
        private System.ComponentModel.Container components = null;
        private System.Windows.Forms.TextBox qualifiedName;
		private System.Windows.Forms.TreeView typeTree;
		private System.Windows.Forms.Button okButton;
		private System.Windows.Forms.Button cancelButton;
        private System.Windows.Forms.Button browseButton;
		private System.Windows.Forms.Label labelBrowser;
		private System.Windows.Forms.Label labelResult;
        private TextBox txtAssembly;
        private Label label1;

        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CacheProviderTypeName));
            this.okButton = new System.Windows.Forms.Button();
            this.cancelButton = new System.Windows.Forms.Button();
            this.qualifiedName = new System.Windows.Forms.TextBox();
            this.browseButton = new System.Windows.Forms.Button();
            this.typeTree = new System.Windows.Forms.TreeView();
            this.labelBrowser = new System.Windows.Forms.Label();
            this.labelResult = new System.Windows.Forms.Label();
            this.txtAssembly = new System.Windows.Forms.TextBox();
            this.label1 = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // okButton
            // 
            this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
            this.okButton.Location = new System.Drawing.Point(299, 289);
            this.okButton.Name = "okButton";
            this.okButton.Size = new System.Drawing.Size(75, 23);
            this.okButton.TabIndex = 0;
            this.okButton.Text = "OK";
            // 
            // cancelButton
            // 
            this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
            this.cancelButton.Location = new System.Drawing.Point(380, 289);
            this.cancelButton.Name = "cancelButton";
            this.cancelButton.Size = new System.Drawing.Size(75, 23);
            this.cancelButton.TabIndex = 1;
            this.cancelButton.Text = "Cancel";
            // 
            // qualifiedName
            // 
            this.qualifiedName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.qualifiedName.Location = new System.Drawing.Point(114, 263);
            this.qualifiedName.Name = "qualifiedName";
            this.qualifiedName.Size = new System.Drawing.Size(341, 20);
            this.qualifiedName.TabIndex = 5;
            this.qualifiedName.TextChanged += new System.EventHandler(this.qualifiedName_TextChanged);
            // 
            // browseButton
            // 
            this.browseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this.browseButton.Location = new System.Drawing.Point(428, 4);
            this.browseButton.Name = "browseButton";
            this.browseButton.Size = new System.Drawing.Size(27, 23);
            this.browseButton.TabIndex = 2;
            this.browseButton.Text = "...";
            this.browseButton.Click += new System.EventHandler(this.browseButton_Click);
            // 
            // typeTree
            // 
            this.typeTree.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.typeTree.Location = new System.Drawing.Point(114, 33);
            this.typeTree.Name = "typeTree";
            this.typeTree.Size = new System.Drawing.Size(341, 224);
            this.typeTree.Sorted = true;
            this.typeTree.TabIndex = 3;
            this.typeTree.DoubleClick += new System.EventHandler(this.typeTree_DoubleClick);
            this.typeTree.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.typeTree_AfterSelect);
            // 
            // labelBrowser
            // 
            this.labelBrowser.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.labelBrowser.Location = new System.Drawing.Point(12, 9);
            this.labelBrowser.Name = "labelBrowser";
            this.labelBrowser.Size = new System.Drawing.Size(96, 16);
            this.labelBrowser.TabIndex = 0;
            this.labelBrowser.Text = "Provider Assembly:";
            // 
            // labelResult
            // 
            this.labelResult.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
            this.labelResult.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.labelResult.Location = new System.Drawing.Point(16, 266);
            this.labelResult.Name = "labelResult";
            this.labelResult.Size = new System.Drawing.Size(92, 16);
            this.labelResult.TabIndex = 6;
            this.labelResult.Text = "Qualified Name:";
            // 
            // txtAssembly
            // 
            this.txtAssembly.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.txtAssembly.Location = new System.Drawing.Point(114, 6);
            this.txtAssembly.Name = "txtAssembly";
            this.txtAssembly.ReadOnly = true;
            this.txtAssembly.Size = new System.Drawing.Size(308, 20);
            this.txtAssembly.TabIndex = 7;
            // 
            // label1
            // 
            this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.label1.Location = new System.Drawing.Point(12, 33);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(96, 16);
            this.label1.TabIndex = 8;
            this.label1.Text = "Provider Type:";
            // 
            // AssemblyQualifiedTypeNameDialog
            // 
            this.AcceptButton = this.okButton;
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.CancelButton = this.cancelButton;
            this.ClientSize = new System.Drawing.Size(462, 318);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.txtAssembly);
            this.Controls.Add(this.labelResult);
            this.Controls.Add(this.labelBrowser);
            this.Controls.Add(this.typeTree);
            this.Controls.Add(this.browseButton);
            this.Controls.Add(this.qualifiedName);
            this.Controls.Add(this.cancelButton);
            this.Controls.Add(this.okButton);
            this.ForeColor = System.Drawing.SystemColors.ControlText;
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "AssemblyQualifiedTypeNameDialog";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
            this.Text = "Cache Provider";
            this.Load += new System.EventHandler(this.QualifiedNameDialog_Load);
            this.ResumeLayout(false);
            this.PerformLayout();

        }
        #endregion

        private string AssemblyName
        {
            get { return this.txtAssembly.Text; }
            set { this.txtAssembly.Text = value; }
        }

        /// <summary>
        /// Gets the type of interface the dialog filters on
        /// </summary>
		public Type InterfaceType
		{
            get { return typeof(ICacheProvider) ;}
			set {}
		}
        
        /// <summary>
        /// Default constructor
        /// </summary>
        public CacheProviderTypeName()
		{
			InitializeComponent();
            if (!string.IsNullOrEmpty(TransmitLocation.Current.Provider))
            {
                int offset = TransmitLocation.Current.Provider.IndexOf(",", 0);
                typeName = TransmitLocation.Current.Provider.Substring(0, offset);
                AssemblyName = TransmitLocation.Current.Provider.Substring(offset + 1).Trim();
                qualifiedName.Text = TransmitLocation.Current.Provider;
            }
		}

		/// <summary>
		/// Clean up any resources
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		private void QualifiedNameDialog_Load(object sender, System.EventArgs e)
		{
			if (!string.IsNullOrEmpty(AssemblyName))
			{
				try
				{
                    Assembly assembly = Assembly.Load(AssemblyName);
					PopulateTree(assembly);
				}
				catch(Exception)
				{
                    TransmitLocation.Current.Provider = string.Empty;
				}
			}
		}

		private void PopulateTree(Assembly assembly)
		{
			typeTree.Nodes.Clear();
			
			AssemblyName = assembly.FullName;
			TreeNode node = new TreeNode(assembly.FullName);
			node.Tag = null;
			typeTree.Nodes.Add(node);
			Type[] types = assembly.GetExportedTypes();
			foreach(Type type in types)
			{
				System.Type[] interfaces = type.FindInterfaces(new TypeFilter(InterfaceFilter), this.InterfaceType);
				TreeNode child = new TreeNode(type.Name);
				if (interfaces.Length == 0)
				{
					child.ForeColor = Color.Gray;
					child.Tag = null;
				}
				else
				{
					child.Tag = type.AssemblyQualifiedName;
				}
				node.Nodes.Add(child);
			}
			node.Expand();
		}
		
		private  bool InterfaceFilter(Type typeObj,Object criteriaObj)
		{
			if(typeObj.ToString() == criteriaObj.ToString())
				return true;
			return false;
		}

		private void browseButton_Click(object sender, System.EventArgs e)
		{
			OpenFileDialog fileDialog = new OpenFileDialog();
			fileDialog.Filter = "Executables(*.dll, *.exe)|*.dll; *.exe" ;
			fileDialog.InitialDirectory = "c:\\Program Files\\Sixeyed.CacheAdapter";
			if (fileDialog.ShowDialog() == DialogResult.OK)
			{
				try
				{
					Assembly assembly = Assembly.LoadFile(fileDialog.FileName);
					PopulateTree(assembly);
				}
				catch(Exception exception)
				{
					throw(new ApplicationException("Qualified Name Dialog: " + exception.Message, exception));
				}
			}
		}

		private void qualifiedName_TextChanged(object sender, System.EventArgs e)
		{
            if (qualifiedName.Text == string.Empty)
            {
                okButton.Enabled = false;
            }
            else
            {
                okButton.Enabled = true;
            }
            TransmitLocation.Current.Provider = qualifiedName.Text;
		}

		private void typeTree_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
		{
			if (e.Node.Tag != null)
			{
                qualifiedName.Text = (string)e.Node.Tag;
			}
		}

		private void typeTree_DoubleClick(object sender, System.EventArgs e)
		{
			string tag = (string)((TreeView)sender).SelectedNode.Tag;
			if (tag != null)
			{
				qualifiedName.Text = tag;
			}
		}

	}
}
